from pml import Objects

class PMError(Objects.object.typeobject):
    def __init__(self, information=None):
        super().__init__('PMError')
        self.informathion = information

    def getObject(self):
        self.methods['__init__'] = self.tp_init
        self.methods['__throw__'] = self.tp_throw

        self.methods['type'] = Objects.object.PMTypeObject(Objects.PMStringObject.PMStringObject('Error').getObject())

        return self

    @staticmethod
    def tp_init(frame, this, information):
        this.information = information.obj.value

    @staticmethod
    def tp_throw(_, this: 'PMError', frame):
        error = '\033[31m'
        error += 'Track:\n'

        track = []
        f = frame
        while True:
            bp = f.bytecodes[f.index].obj.bp.obj if isinstance(f.bytecodes[f.index], Objects.object.PMTypeObject) else f.bytecodes[f.index].bp
            bp = bp.obj if isinstance(bp, Objects.object.PMTypeObject) else bp
            ep = f.bytecodes[f.index].obj.ep.obj if isinstance(f.bytecodes[f.index], Objects.object.PMTypeObject) else f.bytecodes[f.index].ep
            ep = ep.obj if isinstance(ep, Objects.object.PMTypeObject) else ep
            print(bp.column, ep.column)
            track.insert(0, f'\tFile "{bp.filename}" Line {bp.line} column {bp.column}-{ep.column}:\n\t\t[{this.methods["type"]}]{bp.theTextOfTheLine}\n')
            if f.father is None:
                break
            f = f.father
        for t in track:
            error += t

        bp = frame.bytecodes[frame.index].obj.bp.obj if isinstance(frame.bytecodes[frame.index], Objects.object.PMTypeObject) else frame.bytecodes[frame.index].bp
        bp = bp.obj if isinstance(bp, Objects.object.PMTypeObject) else bp
        ep = frame.bytecodes[frame.index].obj.ep.obj if isinstance(frame.bytecodes[frame.index], Objects.object.PMTypeObject) else frame.bytecodes[frame.index].ep
        ep = ep.obj if isinstance(ep, Objects.object.PMTypeObject) else ep

        error += '\t\t' + ' ' * (this.methods['type'].__len__() + bp.column.obj.value + 1) + '^' * (ep.column.obj.value - bp.column.obj.value + 1) + '\n'

        error += f'{this.informathion}\033[0m'

        return error
